<template>
<Transition
  :name="transitionName" 
  @after-leave="destroyComponent"
  @enter="updateHeight"
>
  <div
  class="vk-message"
  v-show="visible"
  :class="{
    [`vk-message--${type}`]:type,
    'is-close':showClose
  }"
  role="alert"
  ref="messageRef"
  :style="cssStyle"
  @mouseenter="clearTimer"
  @mouseleave="startTimer"
  >
     <div class="vk-message__content">
      <slot>
        <RenderVnode :vNode="message" v-if="message"/>
      </slot>
     </div>
     <div class="vk-message__close" v-if="showClose">
      <Icon @click.stop="visible=false" icon="xmark"/>
     </div>
  </div>
</Transition>
</template>


<script setup lang="ts">
import {ref,onMounted, computed} from 'vue';
import type { MessageProps } from './types';
import RenderVnode from '../Common/RenderVnode';
import Icon from '../Icon/IconMain.vue'
import { getLastBottomOffset } from './method';
import useEventListener from '../../hooks/useEventListener'

const props=withDefaults(defineProps<MessageProps>(),{
  type:'info',
  duration: 3000,
  offset:20,
  transitionName:'fade-up'
});
const visible =ref(false)
const messageRef=ref<HTMLDivElement>()
// 计算偏移高度也就是div的高度
const height=ref(0)
//上一个实例底部的坐标数字，第一个底部是0
const lastOffset=computed(()=>getLastBottomOffset(props.id))
//当前元素的top坐标
const topOffset=computed(()=>props.offset+lastOffset.value)
//为下一个元素预留当前元素的bottom坐标
const bottomOffset=computed(()=>height.value+topOffset.value)
const cssStyle=computed(()=>({
  top:topOffset.value+'px',
  zIndex:props.zIndex
}))
let timer:any
function startTimer(){
  if(props.duration === 0) return
  timer=setTimeout(()=>{
    visible.value=false
  },props.duration)
}
function clearTimer(){
  clearTimeout(timer)
}

onMounted(async()=>{
  visible.value=true
  startTimer()
  //确保dom节点已经渲染
  // await nextTick()
  // height.value=messageRef.value!.getBoundingClientRect().height
})
function keydown(e:Event){
  const event =e as KeyboardEvent
  if(event.code==='Escape'){
    visible.value=false
  }
}
useEventListener(document,'keydown',keydown)
//监测消息框关闭的时候销毁节点
// watch(visible,(newValue)=>{
//   if(!newValue){
//     props.onDestory()
//   }
// })

// 关于动画
function destroyComponent(){
  props.onDestory()
}
function updateHeight(){
  height.value=messageRef.value!.getBoundingClientRect().height
}
defineExpose({
  bottomOffset,
  visible
})
</script>

